import { VueNodeView, VueNodeModel } from '@logicflow/vue-node-registry'
import { HtmlNode, HtmlNodeModel } from '@logicflow/core'
import BaseNodeVue from '@/components/logic-editor/nodes/Base/BaseNodeVue.vue'
import { NODE_HEIGHT, NODE_WIDTH } from '@/components/logic-editor/constant'

class BaseNodeModel extends HtmlNodeModel {
  setAttributes() {
    this.width = NODE_WIDTH
    this.height = NODE_HEIGHT
    this.text.editable = false
  }

  getOutlineStyle() {
    const style = super.getOutlineStyle()
    style.stroke = 'none'
    style.hover.stroke = 'none'
    return style
  }
}

class BaseNodeView extends HtmlNode {
  constructor(props) {
    super(props)
    this.mounted = false
    this.vueComponent = h(BaseNodeVue, {
      model: props.model,
      graphModel: props.graphModel,
      disabled: props.graphModel.editConfigModel.isSilentMode,
      isSelected: props.model.isSelected,
      isHovered: props.model.isHovered,
      properties: props.model.getProperties(),
    })
    this.app = createApp({
      render: () => this.vueComponent,
    })
  }

  shouldUpdate() {
    const data = {
      ...this.props.model.properties,
      isSelected: this.props.model.isSelected,
      isHovered: this.props.model.isHovered,
    }
    // console.log('shouldUpdate', data)
    if (this.preProperties && this.preProperties === JSON.stringify(data)) return
    this.preProperties = JSON.stringify(data)
    return true
  }

  setHtml(rootEl) {
    if (!this.isMounted) {
      this.isMounted = true
      this.root = document.createElement('div')
      this.root.className = 'custom-vue-node-content'
      rootEl.appendChild(this.root)
      this.app.mount(this.root)
    } else {
      this.vueComponent.component.props.isSelected = this.props.model.isSelected
      this.vueComponent.component.props.isHovered = this.props.model.isHovered
      this.vueComponent.component.props.properties = this.props.model.getProperties()
    }
  }

  unmountVueComponent() {
    if (this.app) {
      this.app.unmount()
      this.vueComponent = null
      this.app = null
      this.isMounted = false
      this.root.remove()
      this.root = null
    }
  }

  componentWillUnmount() {
    super.componentWillUnmount()
    this.unmountVueComponent()
  }
}

export default {
  type: 'BaseNode',
  view: BaseNodeView,
  model: BaseNodeModel,
}
